package com.powernode.springmvc.controller;


import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.util.UUID;

/**
 * 文件上传：浏览器端向服务器端发送文件，最终服务器将文件保存到服务器上
 */
@Controller
public class FileController {

    @RequestMapping(value = "/fileup",method = RequestMethod.POST)
    //一点上传，就将文件数据给到了multipartFile对象了
    public String fileup(@RequestParam("fileName") MultipartFile multipartFile, HttpServletRequest request) throws Exception {
        //文件上传原理，是IO流
        //面向multipartFile对象做文件上传操作
        String name = multipartFile.getName();
        System.out.println(name);//fileName 获取的是表单name参数的值
        String originalFilename = multipartFile.getOriginalFilename();
        System.out.println(originalFilename);//scenery.jpg 获取的是文件真实的名字

        //一边读，一边写
        //读什么？写什么？
        //读客户端传过来的文件，写到服务器上

        //获取输入流,负责读客户端的文件
        InputStream in = multipartFile.getInputStream();
        //封装成带有缓冲区的输入流
        BufferedInputStream bis = new BufferedInputStream(in);

        //输出流
        //new FilterOutputStream("需要一个文件路径，你准备将文件写到哪？")
        ServletContext application = request.getServletContext();
        String realPath = application.getRealPath("/upload");
        //它会返回Web应用程序根目录下名为 upload 的目录的实际文件系统路径。
        //这个路径是服务器文件系统上的一个绝对路径，可以用来读写文件。
        File file = new File(realPath);
        if(!file.exists()){
            file.mkdirs();
        }
       // File destFile = new File(file.getAbsoluteFile() + "/" +originalFilename); //dest目的操作数 destination目的地
        //这个如果第二个与第一个文件名相同，就会覆盖第一个文件
        File destFile = new File(file.getAbsoluteFile() + "/" + UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf(".")));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));


        //一边读，一边写
        byte[] bytes = new byte[1024*10]; //一次读10KB
        int readCount = 0;
        while ((readCount = bis.read(bytes)) != -1){
            bos.write(bytes,0,readCount);
        }

        bos.flush();
        bos.close();
        bis.close();
        return "ok";
    }

    @RequestMapping(value = "/download",method = RequestMethod.GET)
    //文件下载 （浏览器下载服务器的文件）
    public ResponseEntity<byte[]> downloadFile(HttpServletRequest request) throws IOException {
        File file = new File(request.getServletContext().getRealPath("/upload")+"/scenery.jpg");
        //创建响应头对象
        HttpHeaders headers = new HttpHeaders();
        //设置响应内容类型
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        //设置下载文件的名称
        headers.setContentDispositionFormData("attachment",file.getName());

        //下载文件
        ResponseEntity<byte[]> entity = new ResponseEntity<byte[]>(Files.readAllBytes(file.toPath()),headers,HttpStatus.OK);
        return entity;
    }
}
